/*
 * Copyright (C) 2005-2011 MaNGOS <http://www.getmangos.com/>
 *
 * Copyright (C) 2008-2011 Trinity <http://www.trinitycore.org/>
 *
 * Copyright (C) 2010-2011 Project SkyFire <http://www.projectskyfire.org/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include "gamePCH.h"
#include "Player.h"
#include "Battleground.h"
#include "BattlegroundIC.h"
#include "Language.h"
#include "WorldPacket.h"
#include "GameObject.h"
#include "ObjectMgr.h"
#include "Vehicle.h"
#include "Transport.h"

BattlegroundIC::BattlegroundIC()
{
	m_BgObjects.resize(MAX_NORMAL_GAMEOBJECTS_SPAWNS + MAX_AIRSHIPS_SPAWNS + MAX_HANGAR_TELEPORTERS_SPAWNS + MAX_FORTRESS_TELEPORTERS_SPAWNS);
	m_BgCreatures.resize(MAX_NORMAL_NPCS_SPAWNS + MAX_WORKSHOP_SPAWNS + MAX_DOCKS_SPAWNS + MAX_SPIRIT_GUIDES_SPAWNS);

	m_StartMessageIds[BG_STARTING_EVENT_FIRST]  = LANG_BG_IC_START_TWO_MINUTES;
	m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_IC_START_ONE_MINUTE;
	m_StartMessageIds[BG_STARTING_EVENT_THIRD]  = LANG_BG_IC_START_HALF_MINUTE;
	m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_IC_HAS_BEGUN;

	for (uint8 i = 0; i < 2; i++)
		factionReinforcements[i] = MAX_REINFORCEMENTS;

	for (uint8 i = 0; i < BG_IC_MAXDOOR; i++)
		GateStatus[i] = BG_IC_GATE_OK;

	closeFortressDoorsTimer = CLOSE_DOORS_TIME; // the doors are closed again... in a special way
	doorsClosed = false;
	resourceTimer = IC_RESOURCE_TIME;

	for (uint8 i = NODE_TYPE_REFINERY; i < MAX_NODE_TYPES; i++)
		nodePoint[i] =  nodePointInitial[i];

	siegeEngineWorkshopTimer = WORKSHOP_UPDATE_TIME;

	gunshipHorde = NULL;
	gunshipAlliance = NULL;
}

BattlegroundIC::~BattlegroundIC()
{

}

void BattlegroundIC::HandlePlayerResurrect(Player* player)
{
	if (nodePoint[NODE_TYPE_QUARRY].nodeState == (player->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H))
		player->CastSpell(player,SPELL_QUARRY,true);

	if (nodePoint[NODE_TYPE_REFINERY].nodeState == (player->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H))
		player->CastSpell(player,SPELL_OIL_REFINERY,true);
}

void BattlegroundIC::SendTransportInit(Player* player)
{
	if (!gunshipAlliance || !gunshipHorde)
		return;

	UpdateData transData;

	gunshipAlliance->BuildCreateUpdateBlockForPlayer(&transData, player);
	gunshipHorde->BuildCreateUpdateBlockForPlayer(&transData, player);

	WorldPacket packet;

	transData.BuildPacket(&packet);
	player->GetSession()->SendPacket(&packet);
}

void BattlegroundIC::DoAction(uint32 action, uint64 var)
{
	if (action != ACTION_TELEPORT_PLAYER_TO_TRANSPORT)
		return;

	Player* plr = sObjectMgr.GetPlayer(var);

	if (!plr || !gunshipAlliance || !gunshipHorde)
		return;

	plr->CastSpell(plr,SPELL_PARACHUTE,true); // this must be changed, there is a trigger in each transport that casts the spell.
	plr->CastSpell(plr,SPELL_SLOW_FALL,true);

	plr->SetTransport(plr->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde);

	plr->m_movementInfo.t_pos.m_positionX = TransportMovementInfo.GetPositionX();
	plr->m_movementInfo.t_pos.m_positionY = TransportMovementInfo.GetPositionY();
	plr->m_movementInfo.t_pos.m_positionZ = TransportMovementInfo.GetPositionZ();
	plr->m_movementInfo.t_guid = (plr->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->GetGUID();

	plr->TeleportTo(GetMapId(),TeleportToTransportPosition.GetPositionX(),TeleportToTransportPosition.GetPositionY(),TeleportToTransportPosition.GetPositionZ(),TeleportToTransportPosition.GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT);
}

void BattlegroundIC::Update(uint32 diff)
{
	Battleground::Update(diff);

	if (GetStatus() != STATUS_IN_PROGRESS)
		return;

	if (!doorsClosed)
	{
		if (closeFortressDoorsTimer <= diff)
		{
			GetBGObject(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01)->RemoveFromWorld();
			GetBGObject(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01)->RemoveFromWorld();

			GetBGObject(BG_IC_GO_ALLIANCE_GATE_3)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Alliance door
			GetBGObject(BG_IC_GO_HORDE_GATE_1)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Horde door

			doorsClosed = true;
		} else closeFortressDoorsTimer -= diff;
	}

	for (uint8 i = NODE_TYPE_REFINERY; i < MAX_NODE_TYPES; i++)
	{
		if (nodePoint[i].nodeType == NODE_TYPE_DOCKS)
		{
			if (nodePoint[i].nodeState == NODE_STATE_CONTROLLED_A ||
				nodePoint[i].nodeState == NODE_STATE_CONTROLLED_H)
			{
				if (nodePoint[i].timer <= diff)
				{
					// we need to confirm this, i am not sure if this every 3 minutes
					for (uint8 u = (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_1_A : BG_IC_NPC_CATAPULT_1_H); u < (nodePoint[i].faction  == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_4_A : BG_IC_NPC_CATAPULT_4_H); u++)
					{
						if (Creature* catapult = GetBGCreature(u))
						{
							if (!catapult->isAlive())
								catapult->Respawn(true);
						}
					}

					// we need to confirm this is blizzlike,not sure if it is every 3 minutes
					for (uint8 u = (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_1_A : BG_IC_NPC_GLAIVE_THROWER_1_H); u < (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_2_A : BG_IC_NPC_GLAIVE_THROWER_2_H); u++)
					{
						if (Creature* glaiveThrower = GetBGCreature(u))
						{
							if (!glaiveThrower->isAlive())
								glaiveThrower->Respawn(true);
						}
					}

					docksTimer = DOCKS_UPDATE_TIME;
				} else nodePoint[i].timer -= diff;
			}
		}

		if (nodePoint[i].nodeType == NODE_TYPE_WORKSHOP)
		{
			if (nodePoint[i].nodeState == NODE_STATE_CONTROLLED_A ||
				nodePoint[i].nodeState == NODE_STATE_CONTROLLED_H)
			{
				if (siegeEngineWorkshopTimer <= diff)
				{
					uint8 siegeType = (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_A : BG_IC_NPC_SIEGE_ENGINE_H);

					if (Creature* siege = GetBGCreature(siegeType)) // this always should be true
					{
						if (siege->isAlive())
						{
							if (siege->HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_UNK_14|UNIT_FLAG_OOC_NOT_ATTACKABLE))
								// following sniffs the vehicle always has UNIT_FLAG_UNK_14
								siege->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_OOC_NOT_ATTACKABLE);
							else
								siege->SetHealth(siege->GetMaxHealth());
						}
						else
							siege->Respawn(true);
					}

					// we need to confirm this, i am not sure if this every 3 minutes
					for (uint8 u = (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_A : BG_IC_NPC_DEMOLISHER_1_H); u < (nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_4_A : BG_IC_NPC_DEMOLISHER_4_H); u++)
					{
						if (Creature* demolisher = GetBGCreature(u))
						{
							if (!demolisher->isAlive())
								demolisher->Respawn(true);
						}
					}
					siegeEngineWorkshopTimer = WORKSHOP_UPDATE_TIME;
				} else siegeEngineWorkshopTimer -= diff;
			}
		}

		// the point is waiting for a change on his banner
		if (nodePoint[i].needChange)
		{
			if (nodePoint[i].timer <= diff)
			{
				uint32 nextBanner = GetNextBanner(&nodePoint[i],nodePoint[i].faction,true);

				nodePoint[i].last_entry = nodePoint[i].gameobject_entry;
				nodePoint[i].gameobject_entry = nextBanner;
				// nodePoint[i].faction = the faction should be the same one...

				GameObject* banner = GetBGObject(nodePoint[i].gameobject_type);

				if (!banner) // this should never happen
					return;

				float cords[4] = {banner->GetPositionX(), banner->GetPositionY(), banner->GetPositionZ(), banner->GetOrientation() };

				DelObject(nodePoint[i].gameobject_type);
				AddObject(nodePoint[i].gameobject_type,nodePoint[i].gameobject_entry,cords[0],cords[1],cords[2],cords[3],0,0,0,0,RESPAWN_ONE_DAY);

				GetBGObject(nodePoint[i].gameobject_type)->SetUInt32Value(GAMEOBJECT_FACTION, nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]);

				UpdateNodeWorldState(&nodePoint[i]);
				HandleCapturedNodes(&nodePoint[i],false);

				SendMessage2ToAll(LANG_BG_IC_TEAM_HAS_TAKEN_NODE,CHAT_MSG_BG_SYSTEM_NEUTRAL,NULL,(nodePoint[i].faction == TEAM_ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE),nodePoint[i].string);

				nodePoint[i].needChange = false;
				nodePoint[i].timer = BANNER_STATE_CHANGE_TIME;
			} else nodePoint[i].timer -= diff;
		}
	}

	if (resourceTimer <= diff)
	{
		for (uint8 i = 0; i < NODE_TYPE_DOCKS; i++)
		{
			if (nodePoint[i].nodeState == NODE_STATE_CONTROLLED_A ||
				nodePoint[i].nodeState == NODE_STATE_CONTROLLED_H)
			{
				factionReinforcements[nodePoint[i].faction] += 1;
				RewardHonorToTeam(RESOURCE_HONOR_AMOUNT,nodePoint[i].faction == TEAM_ALLIANCE ? ALLIANCE : HORDE);
				UpdateWorldState((nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_ALLIANCE_RENFORT : BG_IC_HORDE_RENFORT), factionReinforcements[nodePoint[i].faction]);
			}
		}
		resourceTimer = IC_RESOURCE_TIME;
	} else resourceTimer -= diff;
}

void BattlegroundIC::StartingEventCloseDoors()
{
	// Show Full Gate Displays
	GetBGObject(BG_IC_GO_ALLIANCE_GATE_1)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Alliance door
	GetBGObject(BG_IC_GO_ALLIANCE_GATE_2)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Alliance door
	GetBGObject(BG_IC_GO_HORDE_GATE_2)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Horde door
	GetBGObject(BG_IC_GO_HORDE_GATE_3)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Horde door
}

void BattlegroundIC::StartingEventOpenDoors()
{
	//after 20 seconds they should be despawned
	DoorOpen(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01);
	DoorOpen(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01);

	DoorOpen(BG_IC_GO_DOODAD_HU_PORTCULLIS01_1);
	DoorOpen(BG_IC_GO_DOODAD_HU_PORTCULLIS01_2);
	DoorOpen(BG_IC_GO_DOODAD_VR_PORTCULLIS01_1);
	DoorOpen(BG_IC_GO_DOODAD_VR_PORTCULLIS01_2);

	for (uint8 i = 0; i < MAX_FORTRESS_TELEPORTERS_SPAWNS; i++)
	{
		if (!AddObject(BG_IC_Teleporters[i].type,BG_IC_Teleporters[i].entry,
			BG_IC_Teleporters[i].x,BG_IC_Teleporters[i].y,
			BG_IC_Teleporters[i].z,BG_IC_Teleporters[i].o,
			0,0,0,0,RESPAWN_ONE_DAY))
			sLog.outError("Isle of Conquest | Starting Event Open Doors: There was an error spawning gameobject %u",BG_IC_Teleporters[i].entry);
	}
}

bool BattlegroundIC::IsAllNodesConrolledByTeam(uint32 team) const
{
	uint32 count = 0;
	ICNodeState controlledState = team == ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H;
	for (int i = 0; i < NODE_TYPE_WORKSHOP; ++i)
	{
		if (nodePoint[i].nodeState == controlledState)
			count++;
	}

	return count == NODE_TYPE_WORKSHOP;
}

void BattlegroundIC::AddPlayer(Player *plr)
{
	Battleground::AddPlayer(plr);
	//create score and add it to map, default values are set in constructor
	BattlegroundICScore* sc = new BattlegroundICScore;

	m_PlayerScores[plr->GetGUID()] = sc;

	if (nodePoint[NODE_TYPE_QUARRY].nodeState == (plr->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H))
		plr->CastSpell(plr,SPELL_QUARRY,true);

	if (nodePoint[NODE_TYPE_REFINERY].nodeState == (plr->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H))
		plr->CastSpell(plr,SPELL_OIL_REFINERY,true);

	SendTransportInit(plr);
}

void BattlegroundIC::RemovePlayer(Player* plr, uint64 /*guid*/)
{
	plr->RemoveAura(SPELL_QUARRY);
	plr->RemoveAura(SPELL_OIL_REFINERY);
}

void BattlegroundIC::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
{
	// this is wrong way to implement these things. On official it done by gameobject spell cast.
	if (GetStatus() != STATUS_IN_PROGRESS)
		return;
}

void BattlegroundIC::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor)
{
	std::map<uint64, BattlegroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());

	if (itr == m_PlayerScores.end())                         // player not found...
		return;

	switch(type)
	{
	case SCORE_BASES_ASSAULTED:
		((BattlegroundICScore*)itr->second)->BasesAssaulted += value;
		break;
	case SCORE_BASES_DEFENDED:
		((BattlegroundICScore*)itr->second)->BasesDefended += value;
		break;
	default:
		Battleground::UpdatePlayerScore(Source,type,value, doAddHonor);
		break;
	}
}

void BattlegroundIC::FillInitialWorldStates(WorldPacket& data)
{
	data << uint32(BG_IC_ALLIANCE_RENFORT_SET) << uint32(1);
	data << uint32(BG_IC_HORDE_RENFORT_SET) << uint32(1);
	data << uint32(BG_IC_ALLIANCE_RENFORT) << uint32(factionReinforcements[TEAM_ALLIANCE]);
	data << uint32(BG_IC_HORDE_RENFORT) << uint32(factionReinforcements[TEAM_HORDE]);

	for (uint8 i = 0; i < MAX_FORTRESS_GATES_SPAWNS; i++)
	{
		uint32 uws = GetWorldStateFromGateEntry(BG_IC_ObjSpawnlocs[i].entry,(GateStatus[GetGateIDFromEntry(BG_IC_ObjSpawnlocs[i].entry)] == BG_IC_GATE_DESTROYED ? true : false));
		data << uint32(uws) << uint32(1);
	}

	for (uint8 i = 0 ; i < MAX_NODE_TYPES ; i++)
		data << uint32(nodePoint[i].worldStates[nodePoint[i].nodeState]) << uint32(1);
}

bool BattlegroundIC::SetupBattleground()
{
	for (uint8 i = 0; i < MAX_NORMAL_GAMEOBJECTS_SPAWNS; i++)
	{
		if (!AddObject(BG_IC_ObjSpawnlocs[i].type,BG_IC_ObjSpawnlocs[i].entry,
			BG_IC_ObjSpawnlocs[i].x,BG_IC_ObjSpawnlocs[i].y,
			BG_IC_ObjSpawnlocs[i].z,BG_IC_ObjSpawnlocs[i].o,
			0,0,0,0,RESPAWN_ONE_DAY))
		{
			sLog.outError("Isle of Conquest: There was an error spawning gameobject %u",BG_IC_ObjSpawnlocs[i].entry);
			return false;
		}
	}

	for (uint8 i = 0; i < MAX_NORMAL_NPCS_SPAWNS; i++)
	{
		if (!AddCreature(BG_IC_NpcSpawnlocs[i].entry,BG_IC_NpcSpawnlocs[i].type,BG_IC_NpcSpawnlocs[i].team,
			BG_IC_NpcSpawnlocs[i].x,BG_IC_NpcSpawnlocs[i].y,
			BG_IC_NpcSpawnlocs[i].z,BG_IC_NpcSpawnlocs[i].o,
			RESPAWN_ONE_DAY))
		{
			sLog.outError("Isle of Conquest: There was an error spawning creature %u",BG_IC_NpcSpawnlocs[i].entry);
			return false;
		}
	}

	if (!AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+5,BG_IC_SpiritGuidePos[5][0], BG_IC_SpiritGuidePos[5][1],BG_IC_SpiritGuidePos[5][2], BG_IC_SpiritGuidePos[5][3],ALLIANCE)
		|| !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+6,BG_IC_SpiritGuidePos[6][0], BG_IC_SpiritGuidePos[6][1],BG_IC_SpiritGuidePos[6][2], BG_IC_SpiritGuidePos[6][3],HORDE)
		|| !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+3,BG_IC_SpiritGuidePos[7][0], BG_IC_SpiritGuidePos[7][1],BG_IC_SpiritGuidePos[7][2], BG_IC_SpiritGuidePos[7][3],ALLIANCE)
		|| !AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+4,BG_IC_SpiritGuidePos[8][0], BG_IC_SpiritGuidePos[8][1],BG_IC_SpiritGuidePos[8][2], BG_IC_SpiritGuidePos[8][3],HORDE))
	{
		sLog.outError("Isle of Conquest: Failed to spawn initial spirit guide!");
		return false;
	}

	gunshipHorde = CreateTransport(GO_HORDE_GUNSHIP,TRANSPORT_PERIOD_TIME);
	gunshipAlliance = CreateTransport(GO_ALLIANCE_GUNSHIP,TRANSPORT_PERIOD_TIME);

	if (!gunshipAlliance || !gunshipHorde)
	{
		sLog.outError("Isle of Conquest: There was an error creating gunships!");
		return false;
	}

	//Send transport init packet to all player in map
	for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end();itr++)
	{
		if (Player* player = sObjectMgr.GetPlayer(itr->first))
			SendTransportInit(player);
	}

	// setting correct factions for Keep Cannons
	for (uint8 i = BG_IC_NPC_KEEP_CANNON_1; i < BG_IC_NPC_KEEP_CANNON_12; i++)
		GetBGCreature(i)->setFaction(BG_IC_Factions[0]);
	for (uint8 i = BG_IC_NPC_KEEP_CANNON_13; i < BG_IC_NPC_KEEP_CANNON_25; i++)
		GetBGCreature(i)->setFaction(BG_IC_Factions[1]);

	// correcting spawn time for keeps bombs
	for (uint8 i = BG_IC_GO_HUGE_SEAFORIUM_BOMBS_A_1; i < BG_IC_GO_HUGE_SEAFORIUM_BOMBS_H_4; i++)
		GetBGObject(i)->SetRespawnTime(10);

	return true;
}

void BattlegroundIC::HandleKillUnit(Creature *unit, Player* killer)
{
	if (GetStatus() != STATUS_IN_PROGRESS)
		return;

	uint32 entry = unit->GetEntry();
	if (entry == NPC_HIGH_COMMANDER_HALFORD_WYRMBANE)
	{
		RewardHonorToTeam(WINNER_HONOR_AMOUNT,HORDE);
		EndBattleground(HORDE);
	}
	else if (entry == NPC_OVERLORD_AGMAR)
	{
		RewardHonorToTeam(WINNER_HONOR_AMOUNT,ALLIANCE);
		EndBattleground(ALLIANCE);
	}

	//Achievement Mowed Down
	// TO-DO: This should be done on the script of each vehicle of the BG.
	if (unit->IsVehicle())
		killer->CastSpell(killer,SPELL_DESTROYED_VEHICLE_ACHIEVEMENT,true);
}

void BattlegroundIC::HandleKillPlayer(Player* player, Player* killer)
{
	if (GetStatus() != STATUS_IN_PROGRESS)
		return;

	Battleground::HandleKillPlayer(player, killer);

	factionReinforcements[player->GetTeamId()] -= 1;

	UpdateWorldState((player->GetTeamId() == TEAM_ALLIANCE ? BG_IC_ALLIANCE_RENFORT : BG_IC_HORDE_RENFORT), factionReinforcements[player->GetTeamId()]);

	// we must end the battleground
	if (factionReinforcements[player->GetTeamId()] < 1)
		EndBattleground(killer->GetTeam());
}

void BattlegroundIC::EndBattleground(uint32 winner)
{
	SendMessage2ToAll(LANG_BG_IC_TEAM_WINS,CHAT_MSG_BG_SYSTEM_NEUTRAL,NULL, (winner == ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE));

	Battleground::EndBattleground(winner);
}

void BattlegroundIC::RealocatePlayers(ICNodePointType nodeType)
{
	// Those who are waiting to resurrect at this node are taken to the closest own node's graveyard
	std::vector<uint64> ghost_list = m_ReviveQueue[m_BgCreatures[BG_IC_NPC_SPIRIT_GUIDE_1+nodeType-2]];
	if (!ghost_list.empty())
	{
		WorldSafeLocsEntry const *ClosestGrave = NULL;
		for (std::vector<uint64>::const_iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
		{
			Player* plr = sObjectMgr.GetPlayer(*itr);
			if (!plr)
				continue;

			if (!ClosestGrave)                              // cache
				ClosestGrave = GetClosestGraveYard(plr);

			if (ClosestGrave)
				plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation());
		}
	}
}

void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* target_obj)
{
	if (GetStatus() != STATUS_IN_PROGRESS)
		return;

	// All the node points are iterated to find the clicked one
	for (uint8 i = 0; i < MAX_NODE_TYPES; i++)
	{
		if (nodePoint[i].gameobject_entry == target_obj->GetEntry())
		{
			// THIS SHOULD NEEVEER HAPPEN
			if (nodePoint[i].faction == player->GetTeamId())
				return;

			uint32 nextBanner = GetNextBanner(&nodePoint[i],player->GetTeamId(),false);

			// we set the new settings of the nodePoint
			nodePoint[i].faction = player->GetTeamId();
			nodePoint[i].last_entry = nodePoint[i].gameobject_entry;
			nodePoint[i].gameobject_entry = nextBanner;

			// this is just needed if the next banner is grey
			if (nodePoint[i].banners[BANNER_A_CONTESTED] == nextBanner ||
				nodePoint[i].banners[BANNER_H_CONTESTED] == nextBanner)
			{
				nodePoint[i].timer = BANNER_STATE_CHANGE_TIME; // 1 minute for last change (real faction banner)
				nodePoint[i].needChange = true;

				RealocatePlayers(nodePoint[i].nodeType);

				// if we are here means that the point has been lost, or it is the first capture

				if (nodePoint[i].nodeType != NODE_TYPE_REFINERY && nodePoint[i].nodeType != NODE_TYPE_QUARRY)
					if (m_BgCreatures[BG_IC_NPC_SPIRIT_GUIDE_1+(nodePoint[i].nodeType)-2])
						DelCreature(BG_IC_NPC_SPIRIT_GUIDE_1+(nodePoint[i].nodeType)-2);

				UpdatePlayerScore(player, SCORE_BASES_ASSAULTED, 1);

				SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_1,CHAT_MSG_BG_SYSTEM_NEUTRAL,player,nodePoint[i].string);
				SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_2,CHAT_MSG_BG_SYSTEM_NEUTRAL,player,nodePoint[i].string, (player->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE));
				HandleContestedNodes(&nodePoint[i]);
			} else if (nextBanner == nodePoint[i].banners[BANNER_A_CONTROLLED] ||
				nextBanner == nodePoint[i].banners[BANNER_H_CONTROLLED])
				// if we are going to spawn the definitve faction banner, we dont need the timer anymore
			{
				nodePoint[i].timer = BANNER_STATE_CHANGE_TIME;
				nodePoint[i].needChange = false;
				SendMessage2ToAll(LANG_BG_IC_TEAM_DEFENDED_NODE,CHAT_MSG_BG_SYSTEM_NEUTRAL,player,nodePoint[i].string);
				HandleCapturedNodes(&nodePoint[i],true);
				UpdatePlayerScore(player, SCORE_BASES_DEFENDED, 1);
			}

			GameObject* banner = GetBGObject(nodePoint[i].gameobject_type);

			if (!banner) // this should never happen
				return;

			float cords[4] = {banner->GetPositionX(), banner->GetPositionY(), banner->GetPositionZ(), banner->GetOrientation() };

			DelObject(nodePoint[i].gameobject_type);
			AddObject(nodePoint[i].gameobject_type,nodePoint[i].gameobject_entry,cords[0],cords[1],cords[2],cords[3],0,0,0,0,RESPAWN_ONE_DAY);

			GetBGObject(nodePoint[i].gameobject_type)->SetUInt32Value(GAMEOBJECT_FACTION, nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]);

			if (nodePoint[i].nodeType == NODE_TYPE_WORKSHOP)
			{
				DelObject(BG_IC_GO_SEAFORIUM_BOMBS_1);
				DelObject(BG_IC_GO_SEAFORIUM_BOMBS_2);
			}

			UpdateNodeWorldState(&nodePoint[i]);
			// we dont need iterating if we are here
			// If the needChange bool was set true, we will handle the rest in the Update Map function.
			return;
		}
	}
}

void BattlegroundIC::UpdateNodeWorldState(ICNodePoint* nodePoint)
{
	//updating worldstate
	if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTROLLED])
		nodePoint->nodeState = NODE_STATE_CONTROLLED_A;
	else if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTESTED])
		nodePoint->nodeState = NODE_STATE_CONFLICT_A;
	else if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_H_CONTROLLED])
		nodePoint->nodeState = NODE_STATE_CONTROLLED_H;
	else if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_H_CONTESTED])
		nodePoint->nodeState = NODE_STATE_CONFLICT_H;

	uint32 worldstate = nodePoint->worldStates[nodePoint->nodeState];

	// with this we are sure we dont bug the client
	for (uint8 i = 0; i < 4; i++)
		UpdateWorldState(nodePoint->worldStates[i],0);

	UpdateWorldState(worldstate,1);
}

uint32 BattlegroundIC::GetNextBanner(ICNodePoint* nodePoint, uint32 team, bool returnDefinitve)
{
	// this is only used in the update map function
	if (returnDefinitve)
		// here is a special case, here we must return the definitve faction banner after the grey banner was spawned 1 minute
		return nodePoint->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTROLLED : BANNER_H_CONTROLLED)];

	// there were no changes, this point has never been captured by any faction or at least clicked
	if (nodePoint->last_entry == 0)
		// 1 returns the CONTESTED ALLIANCE BANNER, 3 returns the HORDE one
		return nodePoint->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTESTED : BANNER_H_CONTESTED)];

	// If the actual banner is the definitive faction banner, we must return the grey banner of the player's faction
	if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTROLLED] || nodePoint->gameobject_entry == nodePoint->banners[BANNER_H_CONTROLLED])
		return nodePoint->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTESTED : BANNER_H_CONTESTED)];

	// If the actual banner is the grey faction banner, we must return the previous banner
	if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTESTED] || nodePoint->banners[BANNER_H_CONTESTED])
		return nodePoint->last_entry;

	// we should never be here...
	sLog.outError("Isle Of Conquest: Unexpected return in GetNextBanner function");
	return 0;
}

void BattlegroundIC::HandleContestedNodes(ICNodePoint* nodePoint)
{
	if (nodePoint->nodeType == NODE_TYPE_HANGAR)
	{
		if (gunshipAlliance && gunshipHorde)
			(nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->BuildStopMovePacket(GetBgMap());

		for (uint8 u = BG_IC_GO_HANGAR_TELEPORTER_1; u < BG_IC_GO_HANGAR_TELEPORTER_3; u++)
			DelObject(u);
	}
}

void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture)
{
	if(nodePoint->nodeType != NODE_TYPE_REFINERY && nodePoint->nodeType != NODE_TYPE_QUARRY)
	{
		if (!AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+nodePoint->nodeType-2,
			BG_IC_SpiritGuidePos[nodePoint->nodeType][0], BG_IC_SpiritGuidePos[nodePoint->nodeType][1],
			BG_IC_SpiritGuidePos[nodePoint->nodeType][2], BG_IC_SpiritGuidePos[nodePoint->nodeType][3],
			(nodePoint->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE)))
			sLog.outError("Isle of Conquest: Failed to spawn spirit guide! point: %u, team: %u,", nodePoint->nodeType, nodePoint->faction);
	}

	switch(nodePoint->gameobject_type)
	{
	case BG_IC_GO_HANGAR_BANNER:
		// all the players on the stopped transport should be teleported out
		if (!gunshipAlliance || !gunshipHorde)
			break;

		for (uint8 u = 0; u < MAX_HANGAR_TELEPORTERS_SPAWNS; u++)
		{
			uint8 type = BG_IC_GO_HANGAR_TELEPORTER_1+u;
			AddObject(type, (nodePoint->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL : GO_HORDE_GUNSHIP_PORTAL),
				BG_IC_HangarTeleporters[u].GetPositionX(),BG_IC_HangarTeleporters[u].GetPositionY(),
				BG_IC_HangarTeleporters[u].GetPositionZ(),BG_IC_HangarTeleporters[u].GetOrientation(),
				0,0,0,0,RESPAWN_ONE_DAY);
		}

		//sLog.outError("BG_IC_GO_HANGAR_BANNER CAPTURED Faction: %u", nodePoint->faction);

		(nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->BuildStartMovePacket(GetBgMap());
		(nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->BuildStopMovePacket(GetBgMap());
		// we should spawn teleporters
		break;
	case BG_IC_GO_QUARRY_BANNER:
		RemoveAuraOnTeam(SPELL_QUARRY,(nodePoint->faction == TEAM_ALLIANCE ? HORDE : ALLIANCE));
		CastSpellOnTeam(SPELL_QUARRY,(nodePoint->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE));
		break;
	case BG_IC_GO_REFINERY_BANNER:
		RemoveAuraOnTeam(SPELL_OIL_REFINERY,(nodePoint->faction == TEAM_ALLIANCE ? HORDE : ALLIANCE));
		CastSpellOnTeam(SPELL_OIL_REFINERY,(nodePoint->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE));
		break;
	case BG_IC_GO_DOCKS_BANNER:

		if (recapture)
			break;

		if (docksTimer < DOCKS_UPDATE_TIME)
			docksTimer = DOCKS_UPDATE_TIME;

		// we must del opposing faction vehicles when the node is captured (unused ones)
		for (uint8 i = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_1_H : BG_IC_NPC_GLAIVE_THROWER_1_A); i < (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_2_H : BG_IC_NPC_GLAIVE_THROWER_2_A); i++)
		{
			if (Creature* glaiveThrower = GetBGCreature(i))
			{
				if (Vehicle* vehicleGlaive = glaiveThrower->GetVehicleKit())
				{
					if (!vehicleGlaive->GetPassenger(0))
						DelCreature(i);
				}
			}
		}

		for (uint8 i = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_1_H : BG_IC_NPC_CATAPULT_1_A); i < (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_4_H  : BG_IC_NPC_CATAPULT_4_A); i++)
		{
			if (Creature* catapult = GetBGCreature(i))
			{
				if (Vehicle* vehicleGlaive = catapult->GetVehicleKit())
				{
					if (!vehicleGlaive->GetPassenger(0))
						DelCreature(i);
				}
			}
		}

		// spawning glaive throwers
		for (uint8 i = 0; i < MAX_GLAIVE_THROWERS_SPAWNS_PER_FACTION; i++)
		{
			uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_1_A : BG_IC_NPC_GLAIVE_THROWER_1_H)+i;

			if (GetBGCreature(type) && GetBGCreature(type)->isAlive())
				continue;

			if (AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_GLAIVE_THROWER_A : NPC_GLAIVE_THROWER_H,type,nodePoint->faction,
				BG_IC_DocksVehiclesGlaives[i].GetPositionX(),BG_IC_DocksVehiclesGlaives[i].GetPositionY(),
				BG_IC_DocksVehiclesGlaives[i].GetPositionZ(),BG_IC_DocksVehiclesGlaives[i].GetOrientation(),
				RESPAWN_ONE_DAY))
				GetBGCreature(type)->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]);
		}

		// spawning catapults
		for (uint8 i = 0; i < MAX_CATAPULTS_SPAWNS_PER_FACTION; i++)
		{
			uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_1_A : BG_IC_NPC_CATAPULT_1_H)+i;

			if (GetBGCreature(type) && GetBGCreature(type)->isAlive())
				continue;

			if (AddCreature(NPC_CATAPULT,type,nodePoint->faction,
				BG_IC_DocksVehiclesCatapults[i].GetPositionX(),BG_IC_DocksVehiclesCatapults[i].GetPositionY(),
				BG_IC_DocksVehiclesCatapults[i].GetPositionZ(),BG_IC_DocksVehiclesCatapults[i].GetOrientation(),
				RESPAWN_ONE_DAY))
				GetBGCreature(type)->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]);
		}
		break;
	case BG_IC_GO_WORKSHOP_BANNER:
		{
			if (siegeEngineWorkshopTimer < WORKSHOP_UPDATE_TIME)
				siegeEngineWorkshopTimer = WORKSHOP_UPDATE_TIME;

			if (!recapture)
			{
				// we must del opposing faction vehicles when the node is captured (unused ones)
				for (uint8 i = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_H : BG_IC_NPC_DEMOLISHER_1_A); i < (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_4_H : BG_IC_NPC_DEMOLISHER_4_A); i++)
				{
					if (Creature* demolisher = GetBGCreature(i))
					{
						if (Vehicle* vehicleDemolisher = demolisher->GetVehicleKit())
						{
							// is IsVehicleInUse working as expected?
							if (!vehicleDemolisher->IsVehicleInUse())
								DelCreature(i);
						}
					}
				}

				for (uint8 i = 0; i < MAX_DEMOLISHERS_SPAWNS_PER_FACTION; i++)
				{
					uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_A : BG_IC_NPC_DEMOLISHER_1_H)+i;

					if (GetBGCreature(type) && GetBGCreature(type)->isAlive())
						continue;

					if (AddCreature(NPC_DEMOLISHER,type,nodePoint->faction,
						BG_IC_WorkshopVehicles[i].GetPositionX(),BG_IC_WorkshopVehicles[i].GetPositionY(),
						BG_IC_WorkshopVehicles[i].GetPositionZ(),BG_IC_WorkshopVehicles[i].GetOrientation(),
						RESPAWN_ONE_DAY))
						GetBGCreature(type)->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]);
				}

				// we check if the opossing siege engine is in use
				int8 enemySiege = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_H : BG_IC_NPC_SIEGE_ENGINE_A);

				if (Creature* siegeEngine = GetBGCreature(enemySiege))
				{
					if (Vehicle* vehicleSiege = siegeEngine->GetVehicleKit())
					{
						// is VehicleInUse working as expected ?
						if (!vehicleSiege->IsVehicleInUse())
							DelCreature(enemySiege);
					}
				}

				uint8 siegeType = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_A : BG_IC_NPC_SIEGE_ENGINE_H);
				if (!GetBGCreature(siegeType) || !GetBGCreature(siegeType)->isAlive())
				{
					AddCreature((nodePoint->faction == TEAM_ALLIANCE ? NPC_SIEGE_ENGINE_A : NPC_SIEGE_ENGINE_H),siegeType,nodePoint->faction,
						BG_IC_WorkshopVehicles[4].GetPositionX(),BG_IC_WorkshopVehicles[4].GetPositionY(),
						BG_IC_WorkshopVehicles[4].GetPositionZ(),BG_IC_WorkshopVehicles[4].GetOrientation(),
						RESPAWN_ONE_DAY);

					if (Creature* siegeEngine = GetBGCreature(siegeType))
					{
						siegeEngine->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_UNK_14|UNIT_FLAG_OOC_NOT_ATTACKABLE);
						siegeEngine->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]);
					}
				}
			}

			for (uint8 i = 0; i < MAX_WORKSHOP_BOMBS_SPAWNS_PER_FACTION; i++)
			{
				AddObject(BG_IC_GO_SEAFORIUM_BOMBS_1+i,GO_SEAFORIUM_BOMBS,
					workshopBombs[i].GetPositionX(),workshopBombs[i].GetPositionY(),
					workshopBombs[i].GetPositionZ(),workshopBombs[i].GetOrientation(),
					0,0,0,0,10);

				if (GameObject* seaforiumBombs = GetBGObject(BG_IC_GO_SEAFORIUM_BOMBS_1+i))
				{
					seaforiumBombs->SetRespawnTime(10);
					seaforiumBombs->SetUInt32Value(GAMEOBJECT_FACTION,BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]);
				}
			}
			break;
		}
	default:
		break;
	}
}

void BattlegroundIC::DestroyGate(Player* pl, GameObject* go, uint32 /*destroyedEvent*/)
{
	GateStatus[GetGateIDFromEntry(go->GetEntry())] = BG_IC_GATE_DESTROYED;
	uint32 uws_open = GetWorldStateFromGateEntry(go->GetEntry(), true);
	uint32 uws_close = GetWorldStateFromGateEntry(go->GetEntry(), false);
	if (uws_open)
	{
		UpdateWorldState(uws_close,0);
		UpdateWorldState(uws_open, 1);
	}
	DoorOpen((pl->GetTeamId() == TEAM_ALLIANCE ? BG_IC_GO_HORDE_KEEP_PORTCULLIS : BG_IC_GO_DOODAD_PORTCULLISACTIVE02));

	uint32 lang_entry = 0;

	switch(go->GetEntry())
	{
	case GO_HORDE_GATE_1:
		lang_entry = LANG_BG_IC_NORTH_GATE_DESTROYED;
	case GO_HORDE_GATE_2:
	case GO_ALLIANCE_GATE_1:
		lang_entry = LANG_BG_IC_WEST_GATE_DESTROYED;
		break;
	case GO_HORDE_GATE_3:
	case GO_ALLIANCE_GATE_2:
		lang_entry = LANG_BG_IC_EAST_GATE_DESTROYED;
		break;
	case GO_ALLIANCE_GATE_3:
		lang_entry = LANG_BG_IC_SOUTH_GATE_DESTROYED;
		break;
	default:
		break;
	}

	SendMessage2ToAll(lang_entry,CHAT_MSG_BG_SYSTEM_NEUTRAL,NULL,(pl->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_IC_HORDE_KEEP : LANG_BG_IC_ALLIANCE_KEEP));
}

void BattlegroundIC::EventPlayerDamagedGO(Player* /*plr*/, GameObject* /*go*/, uint8 /*hitType*/, uint32 /*destroyedEvent*/)
{

}

WorldSafeLocsEntry const* BattlegroundIC::GetClosestGraveYard(Player* player)
{
	BattlegroundTeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam());

	// Is there any occupied node for this team?
	std::vector<uint8> nodes;
	for (uint8 i = 0; i < MAX_NODE_TYPES; ++i)
		if (nodePoint[i].faction == player->GetTeamId())
			nodes.push_back(i);

	WorldSafeLocsEntry const* good_entry = NULL;
	// If so, select the closest node to place ghost on
	if (!nodes.empty())
	{
		float plr_x = player->GetPositionX();
		float plr_y = player->GetPositionY();

		float mindist = 999999.0f;
		for (uint8 i = 0; i < nodes.size(); ++i)
		{
			WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry(BG_IC_GraveyardIds[nodes[i]]);
			if (!entry)
				continue;
			float dist = (entry->x - plr_x)*(entry->x - plr_x)+(entry->y - plr_y)*(entry->y - plr_y);
			if (mindist > dist)
			{
				mindist = dist;
				good_entry = entry;
			}
		}
		nodes.clear();
	}
	// If not, place ghost on starting location
	if (!good_entry)
		good_entry = sWorldSafeLocsStore.LookupEntry(BG_IC_GraveyardIds[teamIndex+MAX_NODE_TYPES]);

	return good_entry;
}

Transport* BattlegroundIC::CreateTransport(uint32 goEntry,uint32 period)
{
	Transport* t = new Transport(period,0);

	const GameObjectInfo* goinfo = sObjectMgr.GetGameObjectInfo(goEntry);

	if (!goinfo)
	{
		sLog.outErrorDb("Transport ID: %u will not be loaded, gameobject_template missing", goEntry);
		delete t;
		return NULL;
	}

	std::set<uint32> mapsUsed;

	if (!t->GenerateWaypoints(goinfo->moTransport.taxiPathId, mapsUsed))
		// skip transports with empty waypoints list
	{
		sLog.outErrorDb("Transport (path id %u) path size = 0. Transport ignored, check DBC files or transport GO data0 field.",goinfo->moTransport.taxiPathId);
		delete t;
		return NULL;
	}

	uint32 mapid = t->m_WayPoints[0].mapid;

	float x = t->m_WayPoints[0].x;
	float y = t->m_WayPoints[0].y;
	float z =  t->m_WayPoints[0].z;
	float o = 1;

	// creates the Gameobject
	if (!t->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_MO_TRANSPORT),goEntry, mapid, x, y, z, o, 100, 0))
	{
		delete t;
		return NULL;
	}

	//If we someday decide to use the grid to track transports, here:
	t->SetMap(GetBgMap());

	for (uint8 i = 0; i < 5; i++)
		t->AddNPCPassenger(0,(goEntry == GO_HORDE_GUNSHIP ? NPC_HORDE_GUNSHIP_CANNON : NPC_ALLIANCE_GUNSHIP_CANNON), (goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetPositionX() : allianceGunshipPassengers[i].GetPositionX()) , (goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetPositionY() : allianceGunshipPassengers[i].GetPositionY()),(goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetPositionZ() : allianceGunshipPassengers[i].GetPositionZ()), (goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetOrientation() : allianceGunshipPassengers[i].GetOrientation()));

	return t;
}
